Skip to content

Add landing page and contact form - #3

Merged
blindtechmage merged 3 commits into
mainfrom
feature/landing-page-and-contact-form
Aug 9, 2026
Merged

Add landing page and contact form#3
blindtechmage merged 3 commits into
mainfrom
feature/landing-page-and-contact-form

Conversation

@blindtechmage

Copy link
Copy Markdown
Owner

Summary

  • Minimal landing page and nav (Home + Contact only — no dead links for sections that don't exist yet)
  • Full contact form: name/email/topic/message fields, accessible inline validation (submit button stays enabled, errors shown via aria-describedby, focus moves to the first invalid field — not disabled-until-valid, a documented accessibility anti-pattern)
  • Honeypot field + Google reCAPTCHA v2 checkbox (chosen over v3 due to its behavioral scoring risking false positives against keyboard-only/screen-reader interaction patterns) + KV-backed rate limiting
  • Contact submissions relayed via the Gmail API (OAuth2) — Workers doesn't reliably support raw SMTP
  • All contact-form logic (validation, reCAPTCHA verification, rate limiting, Gmail send) factored into pure, unit-tested modules
  • Fixed a real WCAG 2.2 AA violation the axe suite caught (nav link touch-target size/spacing, criterion 2.5.8)

Not yet functional in production

Requires manual setup outside this repo before the contact form actually works: a Cloudflare KV namespace (RATE_LIMIT), Gmail API OAuth2 credentials, and a reCAPTCHA site/secret key pair. See docs/SECURITY.md Open Items.

Test plan

  • npm run typecheck passes
  • npm run lint:js / lint:md / lint:html pass
  • npm run test:unit passes (21 tests, including all new contact-form modules)
  • npm run build succeeds
  • npm run test:e2e passes (5 tests: axe scans on both pages, skip-link, always-enabled submit button, inline-error focus behavior)

🤖 Generated with Claude Code

Minimal landing page (Home + Contact nav only, per the design decision
to avoid dead links for unbuilt sections) and a full contact form:

- Real accessible form markup with a topic select, email/message
  validation, and a submit button that stays enabled with inline
  errors on invalid submission (not disabled-until-valid, which is a
  documented accessibility anti-pattern)
- Honeypot field plus Google reCAPTCHA v2 (checkbox variant, chosen
  over v3's behavioral scoring, which risks penalizing keyboard-only
  and screen-reader interaction patterns) plus KV-backed rate limiting
- Messages relayed via the Gmail API (OAuth2), not raw SMTP, since
  Workers does not reliably support raw SMTP
- All logic (validation, reCAPTCHA verification, rate limiting, Gmail
  send) factored into pure/testable modules with unit test coverage
- Playwright/axe accessibility tests for the contact page, plus a
  keyboard-focus test for the inline-validation error flow

Also fixes a real WCAG 2.2 AA violation the axe suite caught in the
new nav (insufficient touch target size/spacing per criterion 2.5.8).

Requires manual setup before functioning in production: a Cloudflare
KV namespace for rate limiting, Gmail API OAuth2 credentials, and a
reCAPTCHA site/secret key pair (see docs/SECURITY.md Open Items).
LinkedIn, X, and GitHub links, sized/spaced to meet WCAG 2.2 AA
target-size criterion (2.5.8), consistent with the nav.
target="_blank" with rel="noopener noreferrer" (prevents the new tab
from accessing the opening page via window.opener), plus visually
hidden "(opens in a new tab)" text on each link so screen reader users
get advance notice of the context change.
@blindtechmage
blindtechmage merged commit d477093 into main Aug 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants